/*******************************************************************************
DialogKit.cpp

	Author:		LiuDingXi
	e-mail:		liudx@gmail.com
	Date time:	2009-08-07

	Copyright (C) 2009
	All rights reserved.
	
*******************************************************************************/
#include "StdAfx.h"
#include "DialogKitEx.h"
#include "SightKit.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

////////////////////////////////////////////////////////////////////////////////

CDialogKit::CDialogKit()
{
	m_pSightKit = NULL;
}

CDialogKit::~CDialogKit()
{
	Free();
}


BOOL CDialogKit::Free()
{
	if(m_Dialogs.size() > 0)
	{
		list<DIALOG*>::iterator it;
		it = m_Dialogs.begin();
		while(it != m_Dialogs.end())
		{
			DIALOG* pDialog = *it++;

			list<DITEM*>::iterator lit;
			lit = pDialog->ItemList.begin();
			while(lit != pDialog->ItemList.end())
			{
				DITEM* pItem = *lit++;
				delete pItem;
			}
			delete pDialog;
		}
		m_Dialogs.clear();
	}
	//if(m_SprKits.size() > 0)
	//{
	//	list<SKIT*>::iterator it;
	//	it = m_SprKits.begin();
	//	while(it != m_SprKits.end())
	//	{
	//		SKIT* pSkit = *it++;
	//		delete pSkit;
	//	}
	//	m_SprKits.clear();
	//}
	if(m_Controls.size() > 0)
	{
		list<CONTROL*>::iterator it;
		it = m_Controls.begin();
		while(it != m_Controls.end())
		{
			CONTROL* pControl = *it++;

			list<CITEM*>::iterator cit;
			cit = pControl->ItemList.begin();
			while(cit != pControl->ItemList.end())
			{
				CITEM* pItem = *cit++;
				delete pItem;
			}
			delete pControl;
		}
		m_Controls.clear();
	}

	return TRUE;
}

BOOL CDialogKit::Load(CArchive& ar)
{
	TCHAR szFolder[MAX_PATH];
	_tcscpy(szFolder, ar.GetFile()->GetFilePath());
	LPTSTR pTail = PathFindFileName(szFolder);
	if(pTail)
	{
		*pTail = 0;
	}

	CONTROL* pControl = NULL;
	DIALOG* pDialog = NULL;

	CString s;
	while(ar.ReadString(s))
	{
		if(s.IsEmpty())
			continue;
		
		LPCTSTR p = s;
		MoveToBegin(p);
		
		#define IS_TAG(tag)	_tcsnicmp(p, tag, _tcslen(tag)) == 0
		
		if(IS_TAG(_T("import")))
		{
			p += 6;

			CString szFile = ParseOf(p);

			TCHAR szFileName[MAX_PATH];
			_tcscpy(szFileName, szFolder);
			PathAppend(szFileName, szFile);
			
			if(PathFileExists(szFileName))
			{
				//LPCTSTR pExt = PathFindExtension(szFileName);
				//if(pExt && _tcsicmp(pExt, _T(".spr")) == 0)
				//{
				//	SKIT* pSkit = new SKIT;
				//	pSkit->szFile = szFile;
				//	m_SprKits.push_back(pSkit);

				//	CFile file(szFileName, CFile::modeRead);
				//	CArchive spr(&file, CArchive::load);
				//	pSkit->Load(spr);
				//}
			}
			else
			{
				return FALSE;
			}
		}
		else if(IS_TAG(_T("control")))
		{
			pDialog = NULL;
			pControl = NewControl(p+7);
		}
		else if(IS_TAG(_T("ctrl")))
		{
			if(pControl)
			{
				CtrlItemAdd(p+4, pControl, tCtrl);
			}
		}
		else if(IS_TAG(_T("sprite")))
		{
			if(pControl)
			{
				CtrlItemAdd(p+6, pControl, tSprite);
			}
		}
		else if(IS_TAG(_T("dialog")))
		{
			pControl = NULL;
			pDialog = NewDialog(p+6);
		}
		else if(IS_TAG(_T("item")))
		{
			if(pDialog)
			{
				DITEM* pItem = pDialog->AddItem(p+4);
				LinkControl(pItem);
			}
		}

	}	
	return TRUE;
}

BOOL CDialogKit::Store(CArchive& ar)
{
	//if(m_SprKits.size() > 0)
	//{
	//	list<SKIT*>::iterator it;
	//	it = m_SprKits.begin();
	//	while(it != m_SprKits.end())
	//	{
	//		SKIT* pSkit = *it++;
	//		CString szImport(_T("import\t"));
	//		szImport += pSkit->szFile;
	//		szImport += _T("\r\n");
	//		ar.WriteString(szImport);
	//	}
	//}

	//CString szSeparator(_T("\r\n\r\n"));
	//ar.WriteString(szSeparator);

	//if(m_Controls.size() > 0)
	//{
	//	list<CONTROL*>::iterator it;
	//	it = m_Controls.begin();
	//	while(it != m_Controls.end())
	//	{
	//		CONTROL* pControl = *it++;

	//		CString szControl(_T("control\t"));
	//		szControl += pControl->szType + _T("\t");
	//		szControl += pControl->szName + _T("\r\n");
	//		ar.WriteString(szControl);

	//		list<CITEM*>::iterator lit;
	//		lit = pControl->ItemList.begin();
	//		while(lit != pControl->ItemList.end())
	//		{
	//			CITEM* pItem = *lit++;

	//			CString szItem;

	//			switch(pItem->nType)
	//			{
	//			case tSprite:
	//				szItem = _T("\tsprite\t");
	//				break;
	//			case tCtrl:
	//				szItem = _T("\tctrl\t");
	//				break;
	//			}
	//			szItem += pItem->szName + _T("\t");

	//			CString szParam;
	//			szParam.Format(_T("%d %d"), pItem->nPosX, pItem->nPosY);

	//			szItem += szParam + _T("\r\n");

	//			ar.WriteString(szItem);
	//		}
	//	}
	//}
	//
	//ar.WriteString(szSeparator);

	//if(m_Dialogs.size() > 0)
	//{
	//	list<DIALOG*>::iterator it;
	//	it = m_Dialogs.begin();
	//	while(it != m_Dialogs.end())
	//	{
	//		DIALOG* pDialog = *it++;

	//		CString szDialog(_T("dialog\t"));
	//		szDialog += pDialog->szName + _T("\r\n");
	//		ar.WriteString(szDialog);

	//		list<DITEM*>::iterator lit;
	//		lit = pDialog->ItemList.begin();
	//		while(lit != pDialog->ItemList.end())
	//		{
	//			DITEM* pItem = *lit++;

	//			CString szItem("\titem\t");
	//			szItem += pItem->szName + _T("\t");

	//			CString szParam;
	//			szParam.Format(_T("%d %d"), pItem->nPosX, pItem->nPosY);

	//			switch(pItem->nNtfy)
	//			{
	//			case NTF_CLOSE:
	//				szParam += _T("\tIDCLOSE");
	//				break;
	//			case NTF_OK:
	//				szParam += _T("\tIDOK");
	//				break;
	//			case NTF_CANCEL:
	//				szParam += _T("\tIDCANCEL");
	//				break;
	//			}

	//			szItem += szParam + _T("\r\n");

	//			ar.WriteString(szItem);
	//		}
	//	}
	//}
	return TRUE;
}

CDialogKit::CONTROL* CDialogKit::NewControl(LPCTSTR p)
{
	CONTROL* pControl = new CONTROL;
	m_Controls.push_back(pControl);

	pControl->szType = ParseOf(p);
	pControl->szName = ParseOf(p);

	return pControl;
}

CDialogKit::DIALOG* CDialogKit::NewDialog(LPCTSTR p)
{
	DIALOG* pDialog = new DIALOG;
	m_Dialogs.push_back(pDialog);

	pDialog->szName = ParseOf(p);

	return pDialog;
}

CDialogKit::DITEM* CDialogKit::DIALOG::AddItem(LPCTSTR p)
{
	DITEM* pItem = new DITEM;
	ItemList.push_back(pItem);

	pItem->pCtrl = NULL;

	pItem->szName = ParseOf(p);
	pItem->nPosX = ParseOf(p, 0);
	pItem->nPosY = ParseOf(p, 0);

	CString szNotify = ParseOf(p);

	pItem->nNtfy = NTF_NONE;
	if(szNotify == _T("IDOK"))
	{
		pItem->nNtfy = NTF_OK;
	}
	else if(szNotify == _T("IDCLOSE"))
	{
		pItem->nNtfy = NTF_CLOSE;
	}
	else if(szNotify == _T("IDCANCEL"))
	{
		pItem->nNtfy = NTF_CANCEL;
	}

	return pItem;
}

CDialogKit::CITEM* CDialogKit::CtrlItemAdd(LPCTSTR p, CONTROL* pControl, UINT nType)
{
	CITEM* pItem = new CITEM;
	pItem->szName = ParseOf(p);
	pItem->nPosX = ParseOf(p, 0);
	pItem->nPosY = ParseOf(p, 0);
	pItem->nType = nType;

	pItem->pControl = NULL;

	switch(nType)
	{
	case tSprite:
		if(!LinkSprite(pItem))
		{
			printf("Sprite %s NOT Found\n", pItem->szName);
			delete pItem;
			return NULL;
		}
		break;
	case tCtrl:
		{
			list<CONTROL*>::iterator it;
			it = m_Controls.begin();
			while(it != m_Controls.end())
			{
				CONTROL* pCtrl = *it++;
				if(pItem->szName == pCtrl->szName)
				{
					pItem->pControl = pCtrl;
				}
			}
		}
		break;
	}
	pControl->ItemList.push_back(pItem);

	return pItem;
}

BOOL CDialogKit::LinkSprite(CDialogKit::CITEM* pItem)
{
	if(pItem != NULL)
	{
		list<CSightKit::SKIT*>::iterator it;
		it = m_pSightKit->m_SprKits.begin();
		while(it != m_pSightKit->m_SprKits.end())
		{
			CSightKit::SKIT* pSkit = *it++;
			SPRITE* pSprite = pSkit->FindSprite(pItem->szName);
			if(pSprite != NULL)
			{
				pItem->pSprite = pSprite;
				return TRUE;
			}
		}
	}
	return FALSE;
}


BOOL CDialogKit::LinkControl(CDialogKit::DITEM* pDlgItem)
{
	if(pDlgItem != NULL)
	{
		list<CONTROL*>::iterator it;
		it = m_Controls.begin();
		while(it != m_Controls.end())
		{
			CONTROL* pCtrl = *it++;
			if(pDlgItem->szName == pCtrl->szName)
			{
				pDlgItem->pCtrl = pCtrl;
				return TRUE;
			}
		}
	}
	return FALSE;
}

CDialogKit::DIALOG* CDialogKit::FindDialog(LPCTSTR szName)
{
	list<DIALOG*>::iterator it;
	it = m_Dialogs.begin();
	while(it != m_Dialogs.end())
	{
		DIALOG* pDialog = *it++;
		if(pDialog->szName == szName)
		{
			return pDialog;
		}
	}
	return NULL;
}

BOOL CDialogKit::SaveTo(LPCTSTR szPathFile)
{
	try
	{
		CFile file(szPathFile, CFile::modeCreate|CFile::modeWrite);



		file.Close();
		return TRUE;
	}
	catch(CException* e)
	{
		e->ReportError();
		e->Delete();
	}
	return FALSE;
}

void CDialogKit::CONTROL::OnDraw(CDC* pDC, int x, int y)
{
	list<CITEM*>::iterator it;
	it = ItemList.begin();
	while(it != ItemList.end())
	{
		CITEM* pItem = *it++;
		pItem->OnDraw(pDC, x, y);
	}
}

void CDialogKit::CONTROL::OnUpdate()
{
	list<CITEM*>::iterator it;
	it = ItemList.begin();
	while(it != ItemList.end())
	{
		CITEM* pItem = *it++;
		pItem->OnUpdate();
	}
}

bool CDialogKit::CONTROL::HitTest(int x, int y)
{
	list<CITEM*>::iterator it;
	it = ItemList.begin();
	while(it != ItemList.end())
	{
		CITEM* pItem = *it++;
		if(pItem->HitTest(x, y))
		{
			return true;
		}
	}
	return false;
}

void CDialogKit::CONTROL::GetRect(RECT& rect)const
{
	list<CITEM*>::const_iterator it;
	it = ItemList.begin();
	if(it != ItemList.end())
	{
		const CITEM* pItem = *it++;
		pItem->GetRect(rect);

		while(it != ItemList.end())
		{
			const CITEM* pItem = *it++;
			RECT rc;
			pItem->GetRect(rc);

			if(rc.left < rect.left)
				rect.left = rc.left;
			if(rc.right > rect.right)
				rect.right = rc.right;
			if(rc.top < rect.top)
				rect.top = rc.top;
			if(rc.bottom > rect.bottom)
				rect.bottom = rc.bottom;
		}
	}
}

UINT CDialogKit::CONTROL::GetType()const
{
	UINT nType = SceneDat::tControl;
	if(szType == "Sprite")
	{
		nType = SceneDat::tSprite;
	}
	else if(szType == "Box")
	{
		nType = SceneDat::tBox;
	}
	else if(szType == "Button")
	{
		nType = SceneDat::tButton;
	}
	else if(szType == "CheckBox")
	{
		nType = SceneDat::tCheckBox;
	}
	else if(szType == "Progress")
	{
		nType = SceneDat::tProgress;
	}
	else if(szType == "Editor")
	{
		nType = SceneDat::tEditor;
	}
	else if(szType == "TabHead")
	{
		nType = SceneDat::tTabHead;
	}
	else if(szType == "TabView")
	{
		nType = SceneDat::tTabView;
	}
	return nType;
}

void CDialogKit::CITEM::OnDraw(CDC* pDC, int x, int y)
{
	switch(nType)
	{
	case tSprite:
		if(pSprite)
		{
			pSprite->OnDraw(pDC, x+nPosX, y+nPosY, 0);
		}
		break;
	case tCtrl:
		if(pControl)
		{
			pControl->OnDraw(pDC, x+nPosX, y+nPosY);
		}
		break;
	}
}

void CDialogKit::CITEM::OnUpdate()
{
	switch(nType)
	{
	case tSprite:
		if(pSprite)
		{
			pSprite->OnUpdate();
		}
		break;
	case tCtrl:
		if(pControl)
		{
			pControl->OnUpdate();
		}
		break;
	}
}

bool CDialogKit::CITEM::HitTest(int x, int y)
{
	switch(nType)
	{
	case tSprite:
		if(pSprite)
		{
			return pSprite->HitTest(x, y);
		}
		break;
	case tCtrl:
		if(pControl)
		{
			return pControl->HitTest(x, y);
		}
		break;
	}
	return false;
}

void CDialogKit::CITEM::GetRect(RECT& rect)const
{
	switch(nType)
	{
	case tSprite:
		if(pSprite)
		{
			pSprite->GetRect(rect);
			rect.left += nPosX;
			rect.right += nPosX;
			rect.top += nPosY;
			rect.bottom += nPosY;
		}
		break;
	case tCtrl:
		if(pControl)
		{
			pControl->GetRect(rect);
			rect.left += nPosX;
			rect.right += nPosX;
			rect.top += nPosY;
			rect.bottom += nPosY;
		}
		break;
	}
}

void CDialogKit::GetImages(set<SKIT::IMAGE*>& ImgSet)
{
	list<CSightKit::SKIT*>::iterator it;
	it = m_pSightKit->m_SprKits.begin();
	while(it != m_pSightKit->m_SprKits.end())
	{
		CSightKit::SKIT* pSkit = *it++;

		pSkit->GetImages(ImgSet);
	}
}


int CDialogKit::JoinTo(list<CDialogKit::CONTROL*>& refList)
{
	refList.insert(refList.end(), 
		m_Controls.begin(),
		m_Controls.end());

	return m_Controls.size();
}


int CDialogKit::JoinTo(list<CDialogKit::DIALOG*>& refList)
{
	refList.insert(refList.end(), 
		m_Dialogs.begin(),
		m_Dialogs.end());

	return m_Controls.size();
}

void CDialogKit::SetSightKit( CSightKit* kit )
{
	m_pSightKit = kit;
}
void CDialogKit::DITEM::GetRect(RECT& rect)const
{
	if(pCtrl)
	{
		pCtrl->GetRect(rect);
		rect.left += nPosX;
		rect.right += nPosX;
		rect.top += nPosY;
		rect.bottom += nPosY;		
	}
}

BOOL CDialogKit::DIALOG::Build(LPCTSTR szOutput)
{
	CCoder Coder;
	Coder.SetFolder(szOutput);

	TCHAR szSaveFile[MAX_PATH];
	_tcscpy(szSaveFile, szOutput);
	PathAppend(szSaveFile, szName);

	CString szPng(szSaveFile);
	CString szDat(szSaveFile);

	if(!Coder.HasSrcFile(szName))
	{
		Coder.TemplateFor(_T("dialog"), _T("DialogX"), szName, szName);
	}

	Coder.Load(szName + _T(".h"));

	CString szItems;
	szItems = _T("\tenum {\r\n");


	list<DITEM*>::iterator it;
	it = ItemList.begin();
	while(it != ItemList.end())
	{
		DITEM* pItem = *it++;

		CString szDef;
		szDef.Format(_T("\t\t%s = %d,\t//%s\r\n"),
			pItem->szName, pItem->idx, pItem->pCtrl->szType);

		szItems += szDef;
	}

	szItems += _T("\t};\r\n");
	Coder.LnRemove(_T("CONTROL_INDEX_BEGIN"), _T("CONTROL_INDEX_END"));
	Coder.LnInsert(_T("CONTROL_INDEX_BEGIN"), szItems);


	Coder.Save(szName + _T(".h"));
	
	return TRUE;
}